/*
 * @FileName: [LogFactoryUtil.java] 
 * @Package com.bcinfo.upp.log 
 * 
 * 
 * Copyright (c) 2011-2015 BCINFO Technology Limited Com.
 * All rights reserved.
 * 
 * This software is the confidential and proprietary 
 * information of BCINFO Technology Limited Company
 * ("Confidential Information"). You shall not disclose 
 * such Confidential Information and shall use it only
 * in accordance with the terms of the contract agreement 
 * you entered into with RKY.
 * 
 * $Rev: 52 $
 * $LastChangedDate: 2013-11-25 11:41:03 +0800 (Mon, 25 Nov 2013) $
 * $LastChangedBy: wanggc $
 * 
 * @category bcinfo-
 * @version 1.1
 * @author $Author: wanggc $
 *
 * Change History:[Formatter: author date description] <br/>
 * 1
 * 2
 * 3
*/
package com.bcinfo.iccard.log;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.bcinfo.iccard.log.impl.Jdk14LogFactoryImpl;

/**
 * 创建LOG的入口<br/>
 * <p>Description:<br/>
 *    <p>1、直接创建LOG
 *       2、注入新的LogFactory，并替换已创建的LOG
 *
 * <p>For Examples <br/>
 * <PRE>
 *     1、直接使用class创建log对象
 *     Log _log = LogFactoryUtil.getLog(LogFactoryUtil.getClass());
 *     2、直接使用String创建log对象
 *     Log _log = LogFactoryUtil.getLog("LogFactoryUtil");
 *     
 *     
 *     
 * </PRE>
 * <p>
 */
public class LogFactoryUtil
{
    public static Log getLog(Class<?> c)
    {
        return getLog(c.getName());
    }

    public static Log getLog(String name)
    {

        // The following concurrent collection retrieve has the side effect of a
        // memory fence read. This will invalidate all dirty cache data if there
        // are any. If the LogWrapper swap happens before this, the new Log will
        // be visible to the current Thread.

        LogWrapper logWrapper = _logWrappers.get(name);

        if (logWrapper == null)
        {
            logWrapper = new LogWrapper(_logFactory.getLog(name));

            LogWrapper previousLogWrapper = _logWrappers.putIfAbsent(name, logWrapper);

            if (previousLogWrapper != null)
            {
                logWrapper = previousLogWrapper;
            }
        }

        return logWrapper;
    }

    public static void setLogFactory(LogFactory logFactory)
    {
        for (Map.Entry<String, LogWrapper> entry : _logWrappers.entrySet())
        {
            String name = entry.getKey();

            LogWrapper logWrapper = entry.getValue();

            logWrapper.setLog(logFactory.getLog(name));
        }

        // The following volatile write will flush out all cache data. All
        // previously swapped LogWrappers will be visible for any reads after a
        // memory fence read according to the happens-before rules.

        _logFactory = logFactory;
    }

    private static volatile LogFactory                     _logFactory  = new Jdk14LogFactoryImpl();
    private static final ConcurrentMap<String, LogWrapper> _logWrappers = new ConcurrentHashMap<String, LogWrapper>();
}
